﻿#region using
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Schema;
#endregion

namespace XmlGenSharp.Logic.Main
{
  public class Program
  {
    private static string _namespace = "NotSpecified";
    private static string _xsdFileName = null;
    private static bool _multiOutput = true;

    // Application Entry Point

    #region Main(string[] args)
    static void Main(string[] args)
    {
      try
      {
        if (args.Length == 0)
        {
          DisplayUsage();
          return;
        }

        if (!ProcessArgs(args))
          return;

        BindingAnalyzer ba = new BindingAnalyzer(null, _xsdFileName, _namespace);

        if (!_multiOutput)
        {
          // Generate a single file
          SingleOutputAnalyzerContext ac = new SingleOutputAnalyzerContext(ba);
          ba.Analyze(ac);

          GeneratorContext gc = new GeneratorContext(ac.CompoundGenerator, ba.Config, Console.Out);
          ac.CompoundGenerator.Generate(gc);
        }
        else
        {
          // Generate one file per class
          MultiOutputAnalyzerContext ac = new MultiOutputAnalyzerContext(ba);
          ba.Analyze(ac);

          foreach (IGenerator generator in ac.SecondaryGenerators)
          {
            byte[] content = generator.GenerateContent(ba.Config);

            try
            {
              FileStream stream = File.Create(generator.GetFileName());
              stream.Write(content, 0, content.Length);
              stream.Close();
            }
            catch (Exception ex)
            {
              Console.WriteLine("Error: {0}", ex.Message);
            }
          }
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }
    #endregion

    // Private Methods

    #region ProcessArgs(string[] args)
    private static bool ProcessArgs(string[] args)
    {
      int x;

      for (x = 0; x < args.Length - 1; x++)
      {
        if (args[x][0] != '/' && args[x][0] != '-')
          break; // End of options

        // Options are specified in the form
        //   -option:optionInfo
        //
        // For example, to specify the name of the generated .NET namespace, use:
        //   -namespace:MyNamespaceHere

        Match match = Regex.Match(args[x], "^[/-](?<option>[^:]*)($|:(?<optionInfo>.*))");
        if (match == null)
          break;

        string option = match.Groups["option"].Value;
        string optionInfo = null;
        if (match.Groups["optionInfo"] != null)
          optionInfo = match.Groups["optionInfo"].Value;

        switch (option.ToLower())
        {
          case "ns":
          case "namespace":
            if (optionInfo == null)
            {
              Console.WriteLine("No namespace specified");
              return false;
            }

            _namespace = optionInfo;
            break;

          case "multi":
          case "multifile":
          case "multiout":
          case "multioutput":
            _multiOutput = true;
            break;

          default:
            Console.WriteLine("Option '{0}' not recognized", option);
            return false;
        }
      }

      if (x >= args.Length)
      {
        Console.WriteLine("No filename specified");
        return false;
      }

      _xsdFileName = args[x];
      return true;
    }
    #endregion

    #region DisplayUsage()
    private static void DisplayUsage()
    {
      Console.WriteLine("Usage: xgs xsdFileName");
    }
    #endregion

    #region GenerateAdvancedEnum()
    private static void GenerateAdvancedEnum()
    {
      Console.WriteLine("#region using");
      Console.WriteLine("using System;");
      Console.WriteLine("using System.Collections;");
      Console.WriteLine("using System.Collections.Generic;");
      Console.WriteLine("using System.Xml;");
      Console.WriteLine();
      Console.WriteLine("using XmlGenSharp.Lib.Utility;");
      Console.WriteLine("#endregion");
      Console.WriteLine();
      Console.WriteLine("#region pragmas");
      Console.WriteLine("#pragma warning disable 0219");
      Console.WriteLine("#endregion");
      Console.WriteLine();
      Console.WriteLine("namespace {0}", _namespace);
      Console.Write("{");

      // TODO
      //EnumerationInfo enumInfo = new EnumerationInfo(_xsdFileName);
      //AdvancedEnumGenerator aeg = new AdvancedEnumGenerator(Console.Out);
      //aeg.Generate(enumInfo);

      Console.WriteLine("}");
    }
    #endregion
  }
}
